package com.sparrow.common.util;

import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;

/**
 * CRC（循环冗余校验）工具类
 * CRC 是一种哈希函数的简化形式，通过多项式除法对数据生成固定长度的校验值（如 CRC6 生成 6 位校验值）。
 */
public class CRCUtil {

    /**
     * 计算 CRC6 校验码（多项式：x⁶ + x⁴ + x³ + x + 1，即 0x3D）。
     * <p>输入数据通过异或和移位操作生成 6 位校验码。</p>
     * @param data 输入字节数组，不可为 null
     * @return CRC6 校验码（0~63 之间的整数）
     * @throws NullPointerException 当 data 为 null 时抛出
     */
    public static int crc6(byte[] data) {
        int crc = 0;
        for (byte b : data) {
            crc ^= (b & 0xFF) << 2; // 低 8 位数据左移 2 位（等效于乘以 4），与当前 CRC 异或
            for (int i = 0; i < 8; i++) { // 每个字节处理 8 次移位（因为初始左移 2 位，总共有 8+2=10 位？实际按多项式处理）
                if ((crc & 0x80) != 0) { // 最高位（第 8 位）为 1 时，进行多项式异或（0x3D 是 CRC6 的生成多项式）
                    crc = (crc << 1) ^ 0x3D; // 左移 1 位后异或多项式（注意：0x3D 是 6 位多项式，左移后最高位为第 7 位？）
                } else {
                    crc <<= 1; // 左移补 0
                }
            }
            crc &= 0x3F; // 保留低 6 位（0x3F = 0b111111）
        }
        return crc;
    }

    public static void main(String[] args) {
        int c = (1 << 6) - 1;
        System.out.println("6位最大值:" + c + " bits=" + Integer.toBinaryString(c));
        Map<Integer, Integer> counts = new HashMap<>();
        for (int i = 1; i <= 10; i++) {
            String v = String.valueOf(i);
            int crc = crc6(v.getBytes(Charset.forName("UTF8")));
            System.out.println("key=" + i + " crc6="+crc);
        }
    }
}
